package com.atguigu.test.mvc.my;

import com.atguigu.test.mvc.annotation.*;
import com.atguigu.test.mvc.enums.PrivacyTypeEnum;
import com.atguigu.test.util.PrivacyUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Arrays;

/**
 * @author zp
 * @version 1.0
 * @description: 自定义返回值处理器 加密字段数据 处理注解PrivacyEncrypt 标注的方法
 * @date 2023/1/2 16:28
 */
public class MyPrivacyEncryptHandlerMethodReturnValueHandler implements HandlerMethodReturnValueHandler {
    @Override
    public boolean supportsReturnType(MethodParameter returnType) {
        return returnType.hasMethodAnnotation(PrivacyEncrypt.class);
    }

    @Override
    public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
        assert returnValue != null;
        // 获取所有的属性 遍历属性 是否是字符串类 如果是字符串 判断注解类型 根据不同类型注解处理属性
        Field[] fields = returnValue.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            if(field.isAnnotationPresent(PrivacyEncryptCustomer.class)){
                if(!field.getType().equals(String.class)){
                    throw new Exception("类型异常");
                }
                setPrivacyEncryptAnnotation(field,returnValue);
            }
        }
        ObjectMapper mapper=new ObjectMapper();
        String json = mapper.writeValueAsString(returnValue);
        // 获取http的返回
        HttpServletResponse httpServletResponse = webRequest.getNativeResponse(HttpServletResponse.class);
        // 设置返回格式和字符编码
        assert httpServletResponse != null;
        httpServletResponse.setContentType("text/plain;charset=utf-8");
        httpServletResponse.getWriter().println(json);
        // 设置请求已经完毕
        mavContainer.setRequestHandled(true);
    }

    private void setPrivacyEncryptAnnotation(Field field,Object returnValue) throws Exception{
        // 判断字段是否包含PrivacyEncryptCustomer注解 如果包含 判断注解类型
        PrivacyEncryptCustomer privacyEncryptCustomer = field.getAnnotation(PrivacyEncryptCustomer.class);
        // 获取注解 type的类型
        PrivacyTypeEnum typeEnum = privacyEncryptCustomer.type();
        // 获取替换字符
        String symbol = privacyEncryptCustomer.symbol();
        // 获取字段数据
        String value = (String) field.get(returnValue);
        switch (typeEnum){
            case CUSTOMER:
                int prefixNoMaskLen = privacyEncryptCustomer.prefixNoMaskLen();
                int suffixNoMaskLen = privacyEncryptCustomer.suffixNoMaskLen();
                field.set(returnValue,PrivacyUtil.desValue(value,prefixNoMaskLen,suffixNoMaskLen,symbol));
                break;
            case PHONE:
                field.set(returnValue,PrivacyUtil.hidePhone(value));
                break;
            case NAME:
                field.set(returnValue,PrivacyUtil.hideChineseName(value));
                break;
            case ID_CARD:
                field.set(returnValue,PrivacyUtil.hideIDCard(value));
                break;
            case EMAIL:
                field.set(returnValue,PrivacyUtil.hideEmail(value));
                break;
            default:break;
        }
    }
}
